/**
 *
 **/
package mwt.xml.xdbforms.dblayer;

import mwt.xml.xdbforms.dblayer.metadata.CatalogMetaData;
import mwt.xml.xdbforms.dblayer.metadata.TableMetaData;
import mwt.xml.xdbforms.dblayer.query.Query;

/**
 * Factory che permette di effettuare la connessione
 * al database in modo trasparante dal driver usato.
 * Inoltre crea degli oggetti che implementano
 * le interaccie di tipo Query e Metadata, la prima
 * per effettuare le query e la seconda per le estrarre
 * i metadati dal DB.
 *
 * La factory utilizza il pattern Singleton per definire l'unica istanza di tale classe.
 * L'unica istanza viene settata mediante l'invocazione del metodo setInstance
 *
 * NOTA: uso una factory in combinazione con un singleton
 * perchè la configurazione iniziale può cambiare a seconda
 * del contesto. Ossia usando un DriverManager oppure
 * un DataSource definito all'interno di una web application
 * @author Gianfranco Murador
 **/
public abstract class ConnectionFactory {

    private static ConnectionFactory instance;
    private static String database = null;

    /**
     * ritorna il database corrente
     * @return nome del database corrente
     */
    public synchronized static String getDatabase() {
        if (database == null) {
            throw new RuntimeException("ConnectionFactory error: catalog not selected");
        }
        return database;
    }

    /**
     * setta il database corrente
     * @param database
     */
    public synchronized static void setDatabase(String database) {
        ConnectionFactory.database = database;
    }

    /**
     * Fa ritornare un prodotto di tipo QueryService
     **/
    public abstract Query getQuery();

    /**
     * Ritorna l'implementazione dell'interfaccia TableMetaData
     * @see TableMetaData
     * @param table nome delle tabella
     * @return oggetto di tipo TableMetaData
     */
    public abstract TableMetaData getTableMetaData(String table);

    /**
     * Ritorna un'oggetto di tipo CatalogMetaData
     * @return oggetto di tipo CatalogMetadata
     * @see CatalogMetaData
     */
    public abstract CatalogMetaData getDatabaseMetaData();

    /**
     * Costruttore
     */
    protected ConnectionFactory() {
    }

    /**
     * ritorna l'istanza della factory
     *
     **/
    public synchronized static ConnectionFactory getInstance() {

        if (instance == null) {
            throw new RuntimeException("Factory is not initialiated");
        }
        return instance;

    }

    /**
     * setta l'istanza della factory nell'ambiente
     **/
    public synchronized static void setInstance(ConnectionFactory factory) {
        if (instance == null) {
            instance = factory;
        }
    }
}
